Spring Cloud 게 이 트 웨 이 서비스 zuul 동적 경로 의 실현 방법
게 이 트 웨 이 서 비 스 는 데이터 의 유일한 입구 이다.함부로 서 비 스 를 멈 출 수 없다.그래서 동태 적 인 경로 가 특히 필요 하 다.
데이터베이스 동적 루트 는 이벤트 리 셋 메커니즘 을 바탕 으로 zuul 의 루트 속성 을 수정 합 니 다.
DiscoveryClientRouteLocator
Discovery Client RouteLocator 는 기본 새로 고침 의 핵심 처리 클래스 임 을 볼 수 있 습 니 다.
// protected 。 。
protected LinkedHashMap<String, ZuulRoute> locateRoutes()
// RefreshableRouteLocator
public void refresh() {
this.doRefresh();
}
이 두 가지 방법 은 모두 Simple RouteLocator 류 를 계승 하고 재 작업 한 것 이다.사실 공식 적 인 방법 설명 이 있 습 니 다.로드 맵 관 계 를 동적 으로 읽 어야 한다 면.하위 클래스 가 이 두 가지 방법 을 다시 써 야 한다.구체 적 인 실현 을 진행 하 다
우선 pom jar 패키지 가 져 오기 my sql 데이터 베 이 스 를 연결 해 야 합 니 다.
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- jdbc -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
루트 실체 ZuulRouteEntity
package com.xian.cloud.entity;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* <Description>
*
* @author [email protected]
* @version 1.0
* @createDate 2019/10/30 15:00
*/
@Data
public class ZuulRouteEntity implements Serializable {
private static final long serialVersionUID = 1L;
/**
* router Id
*/
private Integer id;
/**
*
*/
private String path;
/**
*
*/
private String serviceId;
/**
* url
*/
private String url;
/**
*
*/
private String stripPrefix;
/**
*
*/
private String retryable;
/**
*
*/
private String enabled;
/**
*
*/
private String sensitiveheadersList;
/**
*
*/
private Date createTime;
/**
*
*/
private Date updateTime;
/**
* (0- ,1- )
*/
private String delFlag;
}
새 Discovery RouteLocator 클래스 의 부모 인터페이스 가 변 하지 않 습 니 다.
package com.xian.cloud.router;
import com.google.common.base.Strings;
import com.google.common.collect.Sets;
import com.xian.cloud.entity.ZuulRoute;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.netflix.zuul.filters.RefreshableRouteLocator;
import org.springframework.cloud.netflix.zuul.filters.SimpleRouteLocator;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.util.StringUtils;
import java.util.*;
/**
* <Description>
*
* @author [email protected]
* @version 1.0
* @createDate 2019/10/30 18:57
*/
@Slf4j
public class DiscoveryRouteLocator extends SimpleRouteLocator implements RefreshableRouteLocator {
private ZuulProperties properties;
private JdbcTemplate jdbcTemplate;
public DiscoveryRouteLocator(String servletPath, ZuulProperties properties, JdbcTemplate jdbcTemplate) {
super(servletPath, properties);
this.properties = properties;
this.jdbcTemplate = jdbcTemplate;
log.info("servletPath:{}",servletPath);
}
@Override
public void refresh() {
doRefresh();
}
@Override
protected Map<String, ZuulProperties.ZuulRoute> locateRoutes() {
LinkedHashMap<String, ZuulProperties.ZuulRoute> routesMap = new LinkedHashMap<String, ZuulProperties.ZuulRoute>();
//
routesMap.putAll(super.locateRoutes());
//
routesMap.putAll(getRouteList());
//
LinkedHashMap<String, ZuulProperties.ZuulRoute> values = new LinkedHashMap<>();
for (Map.Entry<String, ZuulProperties.ZuulRoute> entry : routesMap.entrySet()) {
String path = entry.getKey();
// Prepend with slash if not already present.
if (!path.startsWith("/")) {
path = "/" + path;
}
if (StringUtils.hasText(this.properties.getPrefix())) {
path = this.properties.getPrefix() + path;
if (!path.startsWith("/")) {
path = "/" + path;
}
}
values.put(path, entry.getValue());
}
return values;
}
/**
* zuul
* @return
*/
private LinkedHashMap<String, ZuulProperties.ZuulRoute> getRouteList() {
LinkedHashMap<String, ZuulProperties.ZuulRoute> zuulRoutes = new LinkedHashMap<>();
List<ZuulRoute> sysZuulRoutes = jdbcTemplate.query("select * from sys_zuul_route where del_flag = 0", new BeanPropertyRowMapper<>(ZuulRoute.class));
for (ZuulRoute route: sysZuulRoutes) {
//
if (Strings.isNullOrEmpty(route.getPath()) && Strings.isNullOrEmpty(route.getUrl())) {
continue;
}
ZuulProperties.ZuulRoute zuulRoute = new ZuulProperties.ZuulRoute();
try {
zuulRoute.setId(route.getServiceId());
zuulRoute.setPath(route.getPath());
zuulRoute.setServiceId(route.getServiceId());
zuulRoute.setRetryable(Objects.equals("0", route.getRetryable()) ? Boolean.FALSE : Boolean.TRUE);
zuulRoute.setStripPrefix(Objects.equals("0", route.getStripPrefix()) ? Boolean.FALSE : Boolean.TRUE);
zuulRoute.setUrl(route.getUrl());
List<String> sensitiveHeadersList = Arrays.asList(route.getSensitiveheadersList().split(","));
if (sensitiveHeadersList != null) {
Set<String> sensitiveHeaderSet = Sets.newHashSet();
sensitiveHeadersList.forEach(sensitiveHeader -> sensitiveHeaderSet.add(sensitiveHeader));
zuulRoute.setSensitiveHeaders(sensitiveHeaderSet);
zuulRoute.setCustomSensitiveHeaders(true);
}
} catch (Exception e) {
log.error(" ", e);
}
log.info(" ,path:{},serviceId:{}", zuulRoute.getPath(), zuulRoute.getServiceId());
zuulRoutes.put(zuulRoute.getPath(), zuulRoute);
}
return zuulRoutes;
}
}
우 리 는 또 하나의 사건 의 생산자 와 소비자 가 직접 그림 을 그 려 서 하나의 유형 에 편리 하 게 통합 시 켜 야 한다.
package com.xian.cloud.event;
import com.xian.cloud.router.DiscoveryRouteLocator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.discovery.event.HeartbeatEvent;
import org.springframework.cloud.client.discovery.event.HeartbeatMonitor;
import org.springframework.cloud.context.scope.refresh.RefreshScopeRefreshedEvent;
import org.springframework.cloud.netflix.zuul.RoutesRefreshedEvent;
import org.springframework.cloud.netflix.zuul.web.ZuulHandlerMapping;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Service;
/**
* <Description> ,
*
* @author [email protected]
* @version 1.0
* @createDate 2019/10/30 15:27
*/
@Service
public class RefreshRouteService implements ApplicationListener<ApplicationEvent> {
@Autowired
private ZuulHandlerMapping zuulHandlerMapping;
private HeartbeatMonitor heartbeatMonitor = new HeartbeatMonitor();
@Autowired
ApplicationEventPublisher publisher;
@Autowired
private DiscoveryRouteLocator dynamicRouteLocator;
/**
* refreshRoute()
*/
public void refreshRoute() {
RoutesRefreshedEvent routesRefreshedEvent = new RoutesRefreshedEvent(dynamicRouteLocator);
publisher.publishEvent(routesRefreshedEvent);
}
/**
* 。
* @param event
*/
@Override
public void onApplicationEvent(ApplicationEvent event) {
if(event instanceof ContextRefreshedEvent || event instanceof RefreshScopeRefreshedEvent || event instanceof RoutesRefreshedEvent){
// 。 ,
zuulHandlerMapping.setDirty(true);
}else if(event instanceof HeartbeatEvent){
// , 。
HeartbeatEvent heartbeatEvent = (HeartbeatEvent)event;
if(heartbeatMonitor.update(heartbeatEvent.getValue())){
zuulHandlerMapping.setDirty(true);
}
}
}
}
대외 적 으로 트리거 인 터 페 이 스 를 제공 하 다.
package com.xian.cloud.controller;
import com.xian.cloud.event.RefreshRouteService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* <Description>
*
* @author [email protected]
* @version 1.0
* @createDate 2019/10/30 20:23
*/
@RestController
public class RefreshController {
@Autowired
private RefreshRouteService refreshRouteService;
@GetMapping("/refresh")
public String refresh() {
refreshRouteService.refreshRoute();
return "refresh";
}
}
데이터베이스 테이블 구조
CREATE TABLE `sys_zuul_route` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'router Id',
`path` varchar(255) NOT NULL COMMENT ' ',
`service_id` varchar(255) NOT NULL COMMENT ' ',
`url` varchar(255) DEFAULT NULL COMMENT 'url ',
`strip_prefix` char(1) DEFAULT '1' COMMENT ' ',
`retryable` char(1) DEFAULT '1' COMMENT ' ',
`enabled` char(1) DEFAULT '1' COMMENT ' ',
`sensitiveHeaders_list` varchar(255) DEFAULT NULL COMMENT ' ',
`create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT ' ',
`update_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT ' ',
`del_flag` char(1) DEFAULT '0' COMMENT ' (0- ,1- )',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT=' '
프로필 client 소비자 서비스 루트 설정 설명 을 삭제 합 니 다.데이터 원본 설정.데이터베이스 에서 읽 기
시작 서비스 인쇄 로그
2019-10-30 20:49:39.946 INFO 63449 --- [TaskScheduler-1] c.xian.cloud.router.DynamicRouteLocator : 데이터베이스 사용자 정의 경로 설정 추가,path:/client/*,serviceId:cloud-discovery-client
2019-10-30 20:49:40.397 INFO 63449 --- [TaskScheduler-1] c.xian.cloud.router.DynamicRouteLocator : 데이터베이스 사용자 정의 경로 설정 추가,path:/client/*,serviceId:cloud-discovery-client
postman 클 라 이언 트 인터페이스 요청 전송 성공 여부
zuul 동적 게 이 트 웨 이 경로 기반 완료.
총결산
위 에서 말 한 것 은 편집장 이 소개 한 Spring Cloud 게 이 트 웨 이 서비스 zuul 입 니 다. 동적 경로 의 실현 방법 은 여러분 에 게 도움 이 되 기 를 바 랍 니 다.만약 에 궁금 한 점 이 있 으 면 저 에 게 메 시 지 를 남 겨 주세요.편집장 은 신속하게 여러분 에 게 대답 할 것 입 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!
만약 당신 이 본문 이 당신 에 게 도움 이 된다 고 생각한다 면,전 재 를 환영 합 니 다.번 거 로 우 시 겠 지만 출처 를 밝 혀 주 십시오.감사합니다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
thymeleaf로 HTML 페이지를 동적으로 만듭니다 (spring + gradle)지난번에는 에서 화면에 HTML을 표시했습니다. 이번에는 화면을 동적으로 움직여보고 싶기 때문에 입력한 문자를 화면에 표시시키고 싶습니다. 초보자의 비망록이므로 이상한 점 등 있으면 지적 받을 수 있으면 기쁩니다! ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.